package com.jl;

import cn.hutool.extra.ssh.JschUtil;
import cn.hutool.extra.ssh.Sftp;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.SneakyThrows;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * ssh工具类
 */
public class JLSSH {

    @SneakyThrows
    public static Session getSession(String host, int port, String user, String pass) {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        session.setPassword(pass);
        Properties config = new Properties();
        //在代码里需要跳过检测。否则会报错找不到主机
        config.put("StrictHostKeyChecking", "no");
        //为Session对象设置properties
        session.setConfig(config);
        //设置timeout时间
        session.setTimeout(30000);
        session.connect();
        return session;
    }

    /**
     * 执行命令
     *
     * @param host    地址
     * @param port    端口
     * @param user    用户名
     * @param pass    密码
     * @param command 命令
     */
    @SneakyThrows
    public static String exec(String host, int port, String user, String pass, String command) {
        Session session = getSession(host, port, user, pass);
        String exec = exec(session, command);
        session.disconnect();
        return exec;
    }

    /**
     * 执行命令
     *
     * @param session 连接对象
     * @param command 命令
     */
    @SneakyThrows
    public static String exec(Session session, String command) {
        StringBuffer stringBuffer = new StringBuffer();
        ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
        channelExec.setCommand(command);
        channelExec.setInputStream(null);
        channelExec.setErrStream(System.err);
        channelExec.connect();
        BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
        String msg;
        while ((msg = in.readLine()) != null) {
            stringBuffer.append(msg);
        }
        in.close();
        channelExec.disconnect();
        session.disconnect();
        return stringBuffer.toString();
    }

    /**
     * 上传文件
     *
     * @param host      地址
     * @param port      端口
     * @param user      用户名
     * @param pass      密码
     * @param localPath 本地路径
     * @param sftpPath  服务器路径
     */
    @SneakyThrows
    public static void upload(String host, int port, String user, String pass, String localPath, String sftpPath) {
        Session session = getSession(host, port, user, pass);
        upload(session, localPath, sftpPath);
        session.disconnect();
    }

    /**
     * 上传文件
     *
     * @param session   连接对象
     * @param localPath 本地路径
     * @param sftpPath  服务器路径
     */
    @SneakyThrows
    public static void upload(Session session, String localPath, String sftpPath) {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.put(localPath, sftpPath);
        channelSftp.disconnect();
    }

    /**
     * 上传文件
     *
     * @param host        地址
     * @param port        端口
     * @param user        用户名
     * @param pass        密码
     * @param inputStream 上传流
     * @param sftpPath    服务器路径
     */
    @SneakyThrows
    public static void upload(String host, int port, String user, String pass, InputStream inputStream, String sftpPath) {
        Session session = getSession(host, port, user, pass);
        upload(session, inputStream, sftpPath);
        session.disconnect();
    }

    /**
     * 上传文件
     *
     * @param session     连接对象
     * @param inputStream 上传流
     * @param sftpPath    服务器路径
     */
    @SneakyThrows
    public static void upload(Session session, InputStream inputStream, String sftpPath) {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.put(inputStream, sftpPath);
        channelSftp.disconnect();
    }

    /**
     * 下载文件
     *
     * @param host      地址
     * @param port      端口
     * @param user      用户名
     * @param pass      密码
     * @param localPath 本地路径
     * @param sftpPath  服务器路径
     */
    @SneakyThrows
    public static void download(String host, int port, String user, String pass, String localPath, String sftpPath) {
        Session session = getSession(host, port, user, pass);
        download(session, localPath, sftpPath);
        session.disconnect();
    }

    /**
     * 下载文件
     *
     * @param session   连接对象
     * @param localPath 本地路径
     * @param sftpPath  服务器路径
     */
    @SneakyThrows
    public static void download(Session session, String localPath, String sftpPath) {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.get(sftpPath, localPath);
        channelSftp.disconnect();
    }

}
